#!/bin/bash
# ************************************************************
# @author: LANSHANQUAN
# @date: 2021/06/20
# @modify: 2023/12/21
# @function: Init OS by myself!
# Copyright © 2021 - 2025 lsq.tech.All Rights Reserved.
# ************************************************************

startTime=`date +%Y-%m-%d_%H:%M:%S`
startTime_s=`date +%s`

BASE_DIR="/cloud"
DB_DIR="/cloud/db"
APP_DIR="/cloud/apps"
MY_APP_DIR_V1="/cloud/myapps/v1"
MY_APP_DIR_V2="/cloud/myapps/v2"
TMP_DIR="/cloud/tmp"
UTIL_DIR="/cloud/utils"
JDK_DIR="/usr/local/java"
PYTHON_DIR="/usr/local/python"
GCC_DIR="/usr/local/gcc"
TOOLS_DIR="/cloud/tools"
MATH_DIR="/cloud/math"
ML_DIR="/cloud/machinelearning"
DL_DIR="/cloud/deeplearning"

JDK_PKG="jdk-8u241-linux-x64.tar.gz"
PYTHON_PKG="Python-3.8.1.tgz"
GCC_PKG="gcc-8.3.0.tar.xz"
REDIS_PKG="redis-5.0.7.tar.gz"
MYSQL_PKG="mysql-5.7.32-el7-x86_64.tar.gz"
SPARK_PKG="spark-3.0.2-bin-hadoop3.2.tgz"
HADOOP_PKG="hadoop-3.3.0.tar.gz"
ZOOKEEPER_PKG="apache-zookeeper-3.5.7-bin.tar.gz"
KAFKA_PKG="kafka_2.13-2.5.0.tgz"
ROCKETMQ_PKG="rocketmq-all-4.8.0-bin-release.zip"

COMMON_ENV_PATH="/etc/profile"
HADOOP_ENV_PATH="/home/hadoop/.bash_profile"
JAVA_HOME="/usr/local/java/jdk1.8.0_241"
GCC_HOME="/usr/local/gcc"

ITUSER_PASSWORD="Unstoppable2030@tech.com"
DBUSER_PASSWORD="Unstoppable2030@tech.com"
HADOOP_PASSWORD="Unstoppable2030@tech.com"

SSH_PORT=33399
SSH_TIMEOUT=10
SSH_FLAG="SSH_NO_PASSWD_ACCESS_FLAG"

MYSQL_PORT=16603
#MYSQL_PORT=16604
REDIS_PORT=16605
#REDIS_PORT=16606

POSTGRESQL_PORT=16607

ZK_CLIENT_PORT=16608
ZK_CLUSTER_PORT=16609
ZK_ELECT_PORT=16610

KAFKA_PORT=16611

ROCKETMQ_PORT=16612

SPARK_PORT=16614
SPARK_PORT=16615
SPARK_PORT=16616
SPARK_PORT=16617
SPARK_PORT=16618

REDIS_HOME="${DB_DIR}/redis"
REDIS_SRC="${REDIS_HOME}/redis_src"
REDIS_BIN="${REDIS_HOME}/redis_bin"
REDIS_INST_DIR="${REDIS_HOME}/redis{REDIS_PORT}"

MYSQL_HOME="${DB_DIR}/mysql"
MYSQL_INIT_LOG="${DB_DIR}/mysql/mysql${MYSQL_PORT}/mysql_init.log"

APP_UTIL="/home/ituser/AppUtil.sh"
DB_UTIL="/home/dbuser/DbUtil.sh"

DOCKER_UTIL="/home/ituser/DockerUtil.sh"
KUBERNETES_UTIL="/home/ituser/K8sUtil.sh"

MY_APP_UTIL="/cloud/myapps/v2/MyAppUtil.sh"

ZOOKEEPER_HOME="${APP_DIR}/zookeeper"
KAFKA_HOME="${APP_DIR}/kafka"
ROCKETMQ_HOME="${APP_DIR}/rocketmq"
SPARK_HOME="${APP_DIR}/spark"
HADOOP_HOME="${APP_DIR}/hadoop"
HIVE_HOME="${APP_DIR}/hive"

KAFKA_INSTALL_FLAG="${KAFKA_HOME}/kafka_2.13-2.5.0_version.txt"
ROCKETMQ_INSTALL_FLAG="${ROCKETMQ_HOME}/rocketmq_4.8.0_version.txt"
ZK_INSTALL_FLAG="${ZOOKEEPER_HOME}/zookeeper_3.5.7_version.txt"
MYSQL_INSTALL_FLAG="${MYSQL_HOME}/mysql_5.7.32_version.txt"
REDIS_INSTALL_FLAG="${REDIS_HOME}/redis_5.0.7_version.txt"
HADOOP_INSTALL_FLAG="${HADOOP_HOME}/hadoop_3.3.0_version.txt"
SPARK_INSTALL_FLAG="${SPARK_HOME}/spark_3.0.2_version.txt"

BACKUP_IP="172.16.16.2"
CLOUD1_IP="172.16.0.17"
CLOUD2_IP="172.16.16.13"
CLOUD3_IP="172.16.16.4"

BACKUP_IP_EXT="42.193.157.58"
CLOUD1_IP_EXT="106.52.111.18"
CLOUD2_IP_EXT="81.71.73.65"
CLOUD3_IP_EXT="134.175.222.193"


KUBERNETES_ADMIN_CONF="/etc/kubernetes/admin.conf"
KUBERNETES_FLANNEL_CONF="/etc/kubernetes/kube-flannel.yml"

ZK_CONFIG="${ZOOKEEPER_HOME}/conf/zoo.cfg"
ZK_DATA_DIR="${ZOOKEEPER_HOME}/data"
ZK_DATA_LOG_DIR="${ZOOKEEPER_HOME}/datalog"
ZK_CONNECT="${CLOUD1_IP}:${ZK_CLIENT_PORT},${CLOUD2_IP}:${ZK_CLIENT_PORT},${CLOUD3_IP}:${ZK_CLIENT_PORT}"

KAFKA_SERVER_CONFIG="${KAFKA_HOME}/config/server.properties"
KAFKA_CONSUMER_CONFIG="${KAFKA_HOME}/config/consumer.properties"
KAFKA_PRODUCER_CONFIG="${KAFKA_HOME}/config/producer.properties"
KAFKA_LOG_DIR="${KAFKA_HOME}/log"
KAFKA_BOOTSTRAP_SERVERS="${CLOUD1_IP}:${KAFKA_PORT},${CLOUD2_IP}:${KAFKA_PORT},${CLOUD3_IP}:${KAFKA_PORT}"

ROCKETMQ_RUN_SERVER_CONF="${ROCKETMQ_HOME}/bin/runserver.sh"
ROCKETMQ_RUN_BROKER_CONF="${ROCKETMQ_HOME}/bin/runbroker.sh"
ROCKETMQ_BROKER_CONF="${ROCKETMQ_HOME}/conf/broker.conf"
ROCKETMQ_NAMESRV_CONF="${ROCKETMQ_HOME}/conf/namesrv.properties"

HADOOP_CORE_XML="${HADOOP_HOME}/etc/hadoop/core-site.xml"
HADOOP_HDFS_XML="${HADOOP_HOME}/etc/hadoop/hdfs-site.xml"
HADOOP_MAPRED_XML="${HADOOP_HOME}/etc/hadoop/mapred-site.xml"
HADOOP_YARN_XML="${HADOOP_HOME}/etc/hadoop/yarn-site.xml"
HADOOP_ENV_SH="${HADOOP_HOME}/etc/hadoop/hadoop-env.sh"
HADOOP_WORKERS="${HADOOP_HOME}/etc/hadoop/workers"

ADABOOST_HOME="${ML_DIR}/adaboot"
GBDT_HOME="${ML_DIR}/gbdt"
XGBOOST_HOME="${ML_DIR}/xgboost"

TEST_TMP_FILE="${TMP_DIR}/test.tmp"

YUM_EPEL_TEST_REPO="/etc/yum.repos.d/epel-testing.repo"
YUM_KUBERNETES_REPO="/etc/yum.repos.d/kubernetes.repo"
YUM_DOCKER_REPO="/etc/yum.repos.d/docker-ce.repo"
YUM_EPEL_REPO="/etc/yum.repos.d/epel.repo"
YUM_CENTOS_REPO="/etc/yum.repos.d/CentOS-Base.repo"

function checkParam()
{
    echo "[Function] Check param!"

    localIP=`ifconfig eth0 |grep -w "inet" | awk '{print $2}'`
    #echo $localIP
    if [[ $localIP == "$BACKUP_IP" && $1 != "backup" ]];then
        echo "[ERROR] Param error!"
	return 1
    fi
    if [[ $localIP == "$CLOUD1_IP" && $1 != "cloud1" ]];then
        echo "[ERROR] Param error!"
	return 1
    fi
    if [[ $localIP == "$CLOUD2_IP" && $1 != "cloud2" ]];then
        echo "[ERROR] Param error!"
	return 1
    fi
    if [[ $localIP == "$CLOUD3_IP" && $1 != "cloud3" ]];then
        echo "[ERROR] Param error!"
	return 1
    fi
    execUser=`whoami | awk '{printf $0}'`
    if [[ ${execUser} != "root" ]];then
        echo "[ERROR] User error, please use root!"
        return 1
    fi

    printf "[INFO] %-40s is pass!\n" "param"
}

function checkHostname()
{
    echo "[Function] Check hostname!"

    hostname=`hostname`
    fileHostname=`cat /etc/hostname`
    if [[ "$hostname" != "$1" || "$fileHostname" != "$1" ]];then
        echo "$1" > "/etc/hostname"
    fi
    hostname "$1"
    # delete the line which start with 127
    localInfo=`cat /etc/hosts | grep "127.0.0.1"`
    if [[ -n "$localInfo" ]];then
        sed -i "/^127/d" /etc/hosts
    fi
    cloud1Info=`cat /etc/hosts | grep "172.16.0.17"`
    if [[ -z "$cloud1Info" ]];then
        sed -i "1i172.16.0.17     cloud1" /etc/hosts
    fi
    cloud2Info=`cat /etc/hosts | grep "172.16.16.13"`
    if [[ -z "$cloud2Info" ]];then
        sed -i "1i172.16.16.13     cloud2" /etc/hosts
    fi
    cloud3Info=`cat /etc/hosts | grep "172.16.16.4"`
    if [[ -z "$cloud3Info" ]];then
        sed -i "1i172.16.16.4     cloud3" /etc/hosts
    fi
    backupInfo=`cat /etc/hosts | grep "172.16.16.2"`
    if [[ -z "$backupInfo" ]];then
        sed -i "1i172.16.16.2     backup" /etc/hosts
    fi
    printf "[INFO] %-40s is pass!\n" "hostname"
}

function checkTools()
{
    echo "[Function] Check tools and install!"

    echo "[INFO] check expect is installed?"
    rpm -qa | grep expect > /dev/null 2>&1
    if [[ $? -ne 0 ]];then
        echo "[INFO] expect is not installed!"
        yum install -y expect > /dev/null 2>&1
        rpm -qa |grep expect > /dev/null 2>&1
        if [[ $? -eq 0 ]];then
            echo "[INFO] expect install complete!"
        fi
    else
        #echo "[INFO] expect has been installed!"
	printf "[INFO] %-40s is pass!\n" "expect"
    fi
}

function checkPipConf()
{
    echo "[Function] Check pip configuration!"

    if [[ -f /root/.pip/pip.conf ]];then
        echo "[global]" > /root/.pip/pip.conf
        echo "trusted-host=mirrors.aliyun.com" >> /root/.pip/pip.conf
        echo "index-url=http://mirrors.aliyun.com/pypi/simple/" >> /root/.pip/pip.conf
    fi
}

function checkYumConf()
{
    echo "[Function] Check yum configuration!"

    if [[ -f ${YUM_EPEL_TEST_REPO} && -f ${YUM_KUBERNETES_REPO} && -f ${YUM_DOCKER_REPO} && -f ${YUM_EPEL_REPO} && -f ${YUM_CENTOS_REPO} ]];then
        return 0
    fi

    cd /etc/yum.repos.d/ && rm -rfv *

    chown -R ituser: /etc/yum.repos.d
   
    su ituser -c "scp -P ${SSH_PORT} ituser@backup:/etc/yum.repos.d/* /etc/yum.repos.d/"
}

function closeFirewall()
{ 
    echo "[Function] Close firewall!"

    systemctl stop firewalld

    systemctl disable firewalld

    setenforce 0

    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
}

function isDockerInstalled()
{
    echo "[Function] Check is install docker?"

    if [[ "$1"x == "backup"x ]];then
        echo "[INFO] The node is no need install Docker!"
        return 0
    fi

    #if [[ -f /etc/docker/daemon.json ]];then
    #    echo "[INFO] has already install docker!"
    #	return 0
    #fi

    docker version > /dev/null 2>&1

    if [[ $? -eq 0 ]];then
        echo "[INFO] has already install docker!"
	return 0
    fi

    return 1
}

function installDocker()
{
    echo "[Function] install docker, please wait..."

    mkdir /etc/docker

    cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": ["https://6kx4zyno.mirror.aliyuncs.com"]
}
EOF

    yum install docker-ce docker-ce-cli containerd.io -y > /dev/null 2>&1

    if [[ $? -ne 0 ]];then
        echo "[WARN] yum install docker failed, try again!"

        yum install docker-ce docker-ce-cli containerd.io -y

        if [[ $? -ne 0 ]];then
            echo "[ERROR] yum install docker failed!"
	    return 1
        fi
    fi

    docker version

    if [[ $? -eq 0 ]];then
        echo "[INFO] install docker success!"
    fi

    usermod -aG docker ituser

    systemctl daemon-reload

    systemctl restart docker

    systemctl enable docker
}

function isKubernetesInstalled()
{
    echo "[Function] Check is install kubernetes?"

    if [[ "$1"x == "backup"x ]];then
        echo "[INFO] The node is no need install kubernetes!"
        return 0
    fi

    kubeadm version > /dev/null 2>&1

    if [[ $? -ne 0 ]];then
        echo "[WARN] kubernetes kubeadm not installed!"
	return 1
    fi

    echo "[INFO] has install kubernetes!"

    return 0
}

function installKubernetes()
{
    echo "[Function] install kubernetes..."

    yum -y install kubelet-1.23.9-0 kubeadm-1.23.9-0 kubectl-1.23.9-0 > /dev/null 2>&1

    systemctl enable kubelet && systemctl start kubelet

    kubeadm version > /dev/null 2>&1

    if [[ $? -eq 0 ]];then
        echo "[WARN] kubernetes kubeadm install success!"
	return 0
    fi

    chown -R ituser: /etc/kubernetes

    echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
    source ~/.bash_profile

    echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /home/ituser/.bash_profile
    source /home/ituser/.bash_profile

    echo "[INFO] modify containered conf and restart..."

    rm -fv /etc/containerd/config.toml

    systemctl restart containerd
}

function installKubernetesForMaster()
{
    echo "[Function] install kubernetes for master..."

    echo "[INFO] start init master..."

    if [[ $1 != "cloud1" ]];then
        echo "[INFO] No need init..."
        return 0
    fi

    kubeadm init \
    --apiserver-advertise-address=${CLOUD1_IP} \
    --image-repository registry.aliyuncs.com/google_containers \
    --kubernetes-version v1.23.9 \
    --service-cidr=10.96.0.0/12 \
    --pod-network-cidr=10.244.0.0/16 \
    --ignore-preflight-errors=all

    mkdir -p $HOME/.kube
    cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    chown $(id -u):$(id -g) $HOME/.kube/config

    if [[ ! -f ${KUBERNETES_ADMIN_CONF} ]];then
        echo "[ERROR] kubernetes admin conf is not exists!"
        return 1
    fi

    chown -R ituser: /etc/kubernetes

    su ituser -c "scp -P ${SSH_PORT} ${KUBERNETES_ADMIN_CONF} ituser@cloud2:/etc/kubernetes/"
    su ituser -c "scp -P ${SSH_PORT} ${KUBERNETES_ADMIN_CONF} ituser@cloud3:/etc/kubernetes/"

    echo 1 > /proc/sys/net/ipv4/ip_forward
    echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables

    echo "[INFO] start install flannel..."

    if [[ $1 != "cloud1" ]];then
        echo "[INFO] No need install flannel..."
        return 0
    fi

    if [[ ! -f ${KUBERNETES_FLANNEL_CONF} ]];then
        echo "[INFO] get ${KUBERNETES_FLANNEL_CONF} from remote..."
        su ituser -c "scp -P ${SSH_PORT} ituser@backup:/cloud/common/kube-flannel.yml /etc/kubernetes/"
    fi

    if [[ ! -f ${KUBERNETES_FLANNEL_CONF} ]];then
        echo "[ERROR] get ${KUBERNETES_FLANNEL_CONF} from remote failed!"
        return 1
    fi

    kubectl apply -f ${KUBERNETES_FLANNEL_CONF}

    chmod 777 /run/flannel/subnet.env

    echo "[INFO] kubectl get po -n kube-system"

    for i in {0..10}
    do
        kubectl get po -n kube-system
        sleep 3
    done

    echo "[INFO] reference: https://www.imooc.com/wiki/Kubernetes/cItLazChrsMgZ9GwpPU1.html"
}

function checkAiPkgInstall()
{
    echo "[Function] Check AI package and install!"

    if [[ $1 != "${AI_MACHINE}" ]];then
        return 0
    fi
    for module in "numpy" "matplotlib" "pandas" "scipy" "sklearn" "graphviz"
    do
        python3 -c "import ${module}" > /dev/null 2>&1
	if [[ $? -eq 0 ]];then
	    #echo "[INFO] ${module} has been installed!"
            printf "[INFO] %-40s is pass!\n" ${module}
	    continue
	else
	    echo "[WARN] ${module} has not been installed!"
	    if [[ $module == "sklearn" ]];then
	        pip3 install scikit-learn > /dev/null 2>&1
	    else
	        pip3 install ${module} > /dev/null 2>&1
	    fi
	fi
	sleep 3
        python3 -c "import ${module}" > /dev/null 2>&1
	if [[ $? -eq 0 ]];then
	    echo "[INFO] ${module} is installed success!"
	else
	    echo "[INFO] ${module} is installed failed, please check!"
	    return 1
	fi
    done
}

function configSsh()
{
    echo "[Function] Check and modify ssh config file!"

    cat /etc/ssh/sshd_config | grep "PermitRootLogin yes" >/dev/null 2>&1
    if [[ $? -eq 0 ]];then
	sed -i "s/PermitRootLogin.*/PermitRootLogin no/g" /etc/ssh/sshd_config
    fi

    #cat /etc/ssh/sshd_config | grep -e "#Port 22" -e "Port 22"
    cat /etc/ssh/sshd_config | grep "^Port" >/dev/null 2>&1
    if [[ $? -eq 0 ]];then
	#lineNum=`sed -n '/^Port/=' /etc/ssh/sshd_config`
        cat /etc/ssh/sshd_config | grep "^Port ${SSH_PORT}" >/dev/null 2>&1
	if [[ $? -ne 0 ]];then
            sed -i "s/Port.*/Port ${SSH_PORT}/g" /etc/ssh/sshd_config
	else
	    printf "[INFO] %-40s is pass!\n" "ssh config"
            return 0
	fi
    else
        cat /etc/ssh/sshd_config | grep "^#Port" >/dev/null 2>&1
        if [[ $? -eq 0 ]];then
	     linenum=`sed -n '/^#Port/=' /etc/ssh/sshd_config`
	     linenumFirst=`echo $linenum | awk '{printf $1}'`
	     #sed -i "${linenumFirst}d" /etc/ssh/sshd_config
	     sed -i "${linenumFirst}i Port ${SSH_PORT}" /etc/ssh/sshd_config
        fi
    fi

    /bin/systemctl restart sshd.service

    if [[ $? -eq 0 ]];then
        echo "[INFO] restart ssh service success!"
	sleep 3
	lsof -i:${SSH_PORT} >/dev/null 2>&1
        if [[ $? -eq 0 ]];then
            echo "[INFO] ssh service ${SSH_PORT} is listerning!"
	    return 0
        else
            echo "[ERROR] ssh service ${SSH_PORT} is not listerning!"
	    return 1
        fi
    else
        echo "[ERROR] restart ssh service failed!"
	return 1
    fi
    return 1
}

function checkUserPassword()
{
    echo "[Function] Check user password!"

    for name in "dbuser" "hadoop" "ituser"
    do
        passwdExpireFlag=`chage -l $name | grep "password must be changed"`
        if [[ -n "$passwdExpireFlag" ]];then
            echo "[ERROR] ${name} password must be changed!\n"
            if [[ ${name} == "dbuser" ]];then
                echo ${DBUSER_PASSWORD} | passwd --stdin $name
            elif [[ ${name} == "hadoop" ]];then
                echo ${HADOOP_PASSWORD} | passwd --stdin $name
            elif [[ ${name} == "ituser" ]];then
                echo ${ITUSER_PASSWORD} | passwd --stdin $name
            fi
        else
            #echo "[INFO] ${name} password is pass!"
            printf "[INFO] %-40s is pass!\n" ${name}
        fi 
    done
    return 0
}

function checkUser()
{    
    echo "[Function] Check user and group!"

    group=`cat /etc/group |grep -w -o "cloudgroup"`

    if [[ -z "$group" ]];then
        groupadd cloudgroup
    fi

    for name in "dbuser" "hadoop" "ituser"
    do
        if id -u "$name" >/dev/null 2>&1; then
            printf "[INFO] %-40s is pass!\n" $name
        else
            echo "user $name does not exist, then create it!"

            useradd ${name}
            #echo ${password} | passwd --stdin $name
            if [[ ${name} == "dbuser" ]];then
                echo ${DBUSER_PASSWORD} | passwd --stdin $name
            elif [[ ${name} == "hadoop" ]];then
                echo ${HADOOP_PASSWORD} | passwd --stdin $name
            elif [[ ${name} == "ituser" ]];then
                echo ${ITUSER_PASSWORD} | passwd --stdin $name
            fi

            # chage -d 0 -M 180 -W 7 -I 2 $name
            chage -M 180 -W 7 -I 2 $name
        fi

        if ! id $name | grep -w -o "cloudgroup" >/dev/null 2>&1;then
            usermod -a -G cloudgroup $name
        fi
    done
}

function checkDir()
{
    echo "[Function] Check directory!"

    for dir in "${BASE_DIR}" "${DB_DIR}" "${APP_DIR}" "${MY_APP_DIR_V1}" "${MY_APP_DIR_V2}" "${TOOLS_DIR}" "${TMP_DIR}" "${UTIL_DIR}"
    do
        if [[ -d "$dir" ]];then
            printf "[INFO] %-40s is pass!\n" $dir
        else
            mkdir -p "$dir"
        fi
    done
}

function checkMachineLearningDir()
{
    echo "[Function] Check machine learning directory!"

    for dir in "${ADABOOST_HOME}" "${GBDT_HOME}" "${XGBOOST_HOME}"
    do
        if [[ -d "$dir" ]];then
       	    printf "[INFO] %-40s is pass!\n" `basename ${dir}`
        else
            mkdir -p "$dir"
	fi
    done
}

function checkDirPermission()
{
    echo "[Function] Check directory permission!"

    for dir in "${BASE_DIR}" "${APP_DIR}" "${MY_APP_DIR_V1}" "${MY_APP_DIR_V2}" "${TOOLS_DIR}" "${TMP_DIR}" "${UTIL_DIR}"
    do
        chown -R ituser:cloudgroup "$dir"
    done

    chown -R dbuser:cloudgroup ${DB_DIR}

    chmod -R 755 ${BASE_DIR}
    
    chmod -R 777 ${TMP_DIR}
}

function generateUserPubKey()
{
    echo "[Function] Check and generate user public key!"

    for name in "dbuser" "hadoop" "ituser"
    do
        if [ ! -f /home/$name/.ssh/id_rsa ];then
            echo "[INFO] Generate $name id_rsa!"

	    if [[ ! -d /home/$name/.ssh ]];then
		su $name -c "mkdir -p /home/$name/.ssh"
            fi

	    {
		su $name -c "ssh-keygen -t rsa -P \"\" -f /home/$name/.ssh/id_rsa -C \"$name@$1@lsq.tech.com\" > /dev/null 2>&1"
            }&
        else
            #echo "[INFO] $name id_rsa has been created!"
            printf "[INFO] %-40s is pass!\n" $name
        fi
    done
    wait
    return 0
}

function distributePubKey()
{
    echo "[Function] send public key to each host for each user!"

    rm -f /cloud/utils/manully_send_public_key*

    if [[ -f /cloud/utils/manully_send_public_key.txt ]];then
        echo "---------- Use following method to send public key to remote host manully ---------------"  > /cloud/utils/manully_send_public_key.txt
    else
        touch /cloud/utils/manully_send_public_key.txt
    fi

    for hostname in "backup" "cloud1" "cloud2" "cloud3"
    do
        ping -c1 -W1 $hostname >/dev/null 2>&1

	if [[ $? -ne 0 ]];then
	   echo "[ERROR] Ping $hostname failed, pls check!"
	   continue
        fi

        if [[ ${hostname} == "$1" ]];then
	    continue
	fi

        for username in "dbuser" "hadoop" "ituser"
        do
            if [[ $hostname == "backup" && $username == "dbuser" ]];then
	        continue
	    fi

            if [[ $hostname == "cloud1" && $username == "dbuser" ]];then
	        continue
	    fi

            su $username -c "timeout $SSH_TIMEOUT ssh -p $SSH_PORT $username@$hostname >/dev/null 2>&1"
            if [[ $? -eq 0 ]];then
                echo -e "[INFO] Use $username ssh to $username@$hostname no need passwd! \n"
	        continue
	    else
                echo -e "[INFO] Use $username ssh to $username@$hostname need passwd, try build ssh!"
            fi

            {
                #su $username
                if [[ $username == "ituser" ]];then
                    password=${ITUSER_PASSWORD}
                elif [[ $username == "dbuser" ]];then
                    password=${DBUSER_PASSWORD}
                elif [[ $username == "hadoop" ]];then
                    password=${HADOOP_PASSWORD}
                fi

                if [[ ! -f /home/$username/.ssh/authorized_keys ]];then
		    su $username -c "touch /home/$username/.ssh/authorized_keys"
	        fi

		cat > /cloud/utils/manully_send_public_key_$username@$hostname.tmp <<EOF
su $username
ssh-copy-id -p $SSH_PORT -i /home/$username/.ssh/id_rsa.pub $username@$hostname
ssh -p $SSH_PORT $username@$hostname cat /home/$username/.ssh/id_rsa.pub >> /home/$username/.ssh/authorized_keys

EOF

#                /usr/bin/expect > /dev/null 2>&1 <<-EOF
#                set timeout 30
#                spawn ssh-copy-id -i /home/$username/.ssh/id_rsa.pub -p $SSH_PORT $username@$hostname
#                expect {
#                        "*yes/no*" {
#                            send "yes"
#                            expect "*password:*"
#                            send "$password"
#                        }
#                        "*password:*" {
#                            send "$password"
#                        }
#                }
#                expect eof
#EOF
#
#                ssh -p $SSH_PORT $username@$hostname cat /home/$username/.ssh/id_rsa.pub >> /home/$username/.ssh/authorized_keys
#


                sleep 1
            }& 
        done
    done
    wait

    # cat manully_send_public_key*.tmp > manully_send_public_key.txt

    cat /cloud/utils/manully_send_public_key*.tmp > /cloud/utils/manully_send_public_key.txt

    rm -f /cloud/utils/manully_send_public_key*.tmp

    echo "[WARN] If failed, need execute maually, reference /cloud/utils/manully_send_public_key.txt"
    return 0
}

function checkSshIsPass()
{
    echo "[Function] check ssh is pass!"

    for hostname in "backup" "cloud1" "cloud2" "cloud3"
    do
        ping -c1 -W1 $hostname >/dev/null 2>&1
	if [[ $? -ne 0 ]];then
	   echo "[ERROR] Ping $hostname failed, please check!"
	   continue
        fi
        if [[ ${hostname} == "$1" ]];then
	    continue
	fi

        for username in "dbuser" "hadoop" "ituser"
        do
            {
                #sshSuccessFlag=`su $username -c "timeout $SSH_TIMEOUT ssh -p $SSH_PORT $username@$hostname >/dev/null 2>&1 printf $SSH_FLAG"`
		#echo "ssh -p $SSH_PORT $username@$hostname"
                su $username -c "timeout $SSH_TIMEOUT ssh -p $SSH_PORT $username@$hostname >/dev/null 2>&1"
                if [[ $? -eq 0 ]];then
                    echo "[INFO] Use $username ssh to $username@$hostname no need passwd!"
		else
                    echo "[INFO] Use $username ssh to $username@$hostname need passwd, try login manually!"
                fi

                #if [[ $sshSuccessFlag == "$SSH_FLAG" ]];then
                #    echo "[INFO] ssh to $username@$hostname no need passwd!"
		#else
                #    echo "[INFO] ssh to $username@$hostname need passwd or need login manually first!"
                #fi
            }& 
        done
    done
    wait
}

function checkRemoteHostKeyIsUpdate()
{
    echo "[Function] check remote host key is update!"

    for hostname in "backup" "cloud1" "cloud2" "cloud3"
    do
        ping -c1 -W1 $hostname >/dev/null 2>&1
	if [[ $? -ne 0 ]];then
	   echo "[ERROR] Ping $hostname failed, pls check!"
	   continue
        fi
        if [[ ${hostname} == "$1" ]];then
	    continue
	fi

        for username in "dbuser" "hadoop" "ituser"
        do
	    echo "[INFO]  ssh to ${username}@${hostname}!"
            {
                chmod 777 ${TMP_DIR}
                su $username -c "touch ${TEST_TMP_FILE}"
                su $username -c "scp -P $SSH_PORT ${TEST_TMP_FILE} $username@$hostname:${TMP_DIR} 2> ${TMP_DIR}/${username}_ssh_to_${hostname}.log"
                if [[ -f ${TMP_DIR}/${username}_ssh_to_${hostname}.log ]];then
                    cat ${TMP_DIR}/${username}_ssh_to_${hostname}.log | grep "REMOTE HOST IDENTIFICATION HAS CHANGED"
                    if [[ $? -eq 0 ]];then
                        echo "[WARNING] remote host key has changed, please update /home/${username}/.ssh/known_hosts!"
                        su $username -c "sed -i "/${hostname}/d" /home/${username}/.ssh/known_hosts"
                        if [[ $? -eq 0 ]];then
                            echo "[INFO] delete ${hostname} 's key from /home/${username}/.ssh/known_hosts success!"
                        fi
                    fi
                fi

                scp -P $SSH_PORT ${TEST_TMP_FILE} $username@$hostname:${TMP_DIR} 2> ${TMP_DIR}/root_ssh_to_${hostname}.log

                if [[ -f ${TMP_DIR}/root_ssh_to_${hostname}.log ]];then
                    cat ${TMP_DIR}/root_ssh_to_${hostname}.log | grep "REMOTE HOST IDENTIFICATION HAS CHANGED"
                    if [[ $? -eq 0 ]];then
                        echo "[WARNING] remote host key has changed, please update /root/.ssh/known_hosts!"
                        sed -i "/${hostname}/d" /root/.ssh/known_hosts
                        if [[ $? -eq 0 ]];then
                            echo "[INFO] delete ${hostname} 's key from /root/.ssh/known_hosts success!"
                        fi
                    fi
                fi
            }& 

        done
    done
    wait
}

function isJDKInstalled()
{
    echo "[Function] Check JDK8 is installed?"

    . /etc/profile

    if [[ ! -d "$JDK_DIR" ]];then
        echo "No $JDK_DIR!"
        return 1
    fi

    if ! javac -version >/dev/null 2>&1;then
        echo "[WARN] No Java Command!"
        return 2
    fi

    printf "[INFO] %-40s is pass!\n" "JDK"
    return 0
}

function installJDK()
{
    echo "[Function] Install JDK now"

    # tar -zxf /cloud/tools/jdk-8u241-linux-x64.tar.gz -C /usr/local/java/
    echo "JDK pkg path $TOOLS_DIR/$JDK_PKG"

    if [[ ! -f "$TOOLS_DIR/$JDK_PKG" ]];then
        echo "[WARN] pgk $TOOLS_DIR/$JDK_PKG is not exists!"
	su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${JDK_PKG} /cloud/tools"
    fi

    if [[ ! -f "$TOOLS_DIR/$JDK_PKG" ]];then
        echo "[ERROR] pgk $TOOLS_DIR/$JDK_PKG is not exists after scp!"
	return 1
    fi

    echo "Install path $JDK_DIR"
    if [[ ! -d "$JDK_DIR" ]];then
        mkdir -p "$JDK_DIR"
    fi

    tar -zxf "$TOOLS_DIR/$JDK_PKG" -C "$JDK_DIR"
    return 1
}

function checkJDKConfig()
{
    echo "[Function] Check JDK configuration!"

    javaHomeEnv=`cat "$COMMON_ENV_PATH" | grep "JAVA_HOME"`

    if [[ -z $javaHomeEnv ]];then
        echo "JAVA_HOME=$JAVA_HOME" >> "$COMMON_ENV_PATH"
        echo "CLASSPATH=\$JAVA_HOME/lib/" >> "$COMMON_ENV_PATH"
        echo "PATH=$PATH:\$JAVA_HOME/bin" >> "$COMMON_ENV_PATH"
        echo "export PATH JAVA_HOME CLASSPATH" >> "$COMMON_ENV_PATH"
    fi

    . /etc/profile

    printf "[INFO] %-40s is pass!\n" "JDK"
}

function isGccInstalled()
{
    echo "[Function] Check gcc is installed?"

    gccVersion=`gcc --version |grep GCC | awk '{printf $3}'`

    if [[ "$gccVersion" != "8.3.0" ]];then
        echo "[ERROR] gcc version is not 8.3.0!"
        return 3
    else
        return 0
    fi

    if [[ ! -d "$GCC_HOME" ]];then
        echo "No $GCC_HOME!"
        return 1
    fi
    if ! gcc --version >/dev/null 2>&1;then
        echo "[ERROR] No gcc Command!"
        return 2
    fi

    printf "[INFO] %-40s is pass!\n" "gcc"
}

function installGcc()
{
    echo "[Function] Install gcc now"

    echo "gcc pkg path $TOOLS_DIR/$GCC_PKG"
    echo "Install path $GCC_DIR"
    if [[ ! -d "$GCC_DIR" ]];then
        mkdir -p "$GCC_DIR"
    fi

    if [[ ! -f "$TOOLS_DIR/$GCC_PKG" ]];then
        echo "[ERROR] pgk $TOOLS_DIR/$GCC_PKG is not exists!"
        return 1
    fi

    cd "$TOOLS_DIR" && tar -xf "$TOOLS_DIR/$GCC_PKG"
    if [[ $? -eq 0 ]];then
        echo "[ERROR] tar -zxf $TOOLS_DIR/$GCC_PKG failed!"
    fi

    if [[ -d $TOOLS_DIR/gcc-8.3.0 ]];then
        cd $TOOLS_DIR/gcc-8.3.0
    fi

    if [[ `pwd` == "$TOOLS_DIR/gcc-8.3.0" ]];then
        ./contrib/download_prerequisites
        #./configure --prefix=/usr/local/gcc
        ./configure --prefix=/usr/local/gcc --enable-shared --enable-threads=posix --enable-languages=c,c++,fortran --disable-multilib
        make && make install
    fi

    gccEnv=`cat "$COMMON_ENV_PATH" | grep "GCC_HOME"`
    if [[ -z $gccEnv ]];then
        echo "GCC_HOME=$GCC_HOME" >> "$COMMON_ENV_PATH"
        echo "PATH=$PATH:\$GCC_HOME/bin" >> "$COMMON_ENV_PATH"
        echo "export PATH GCC_HOME" >> "$COMMON_ENV_PATH"
    fi
    rm -rf $TOOLS_DIR/gcc-8.3.0
    . $COMMON_ENV_PATH

}
 
function isPythonInstalled()
{
    echo "[Function] Check Python3 is installed?"

    pythonVersion=`python3 --version`
    pythonVersionFlag="True"
    if ! python3 --version >/dev/null 2>&1;then
        pythonVersionFlag="False"
    fi
    if [[ $pythonVersionFlag == "True" && ! $pythonVersion =~ "Python 3" ]];then
        return 1
    fi
    printf "[INFO] %-40s is pass!\n" "Python"
}

function isMysqlInstalled()
{
    echo "[Function] Check MySQL is installed?"

    if [[ "$1"x == "cloud1"x || "$1"x == "backup"x ]];then
        echo "[INFO] The node is no need install MySQL!"
	return 0
    fi

    if [[ ! -f ${MYSQL_INSTALL_FLAG} ]];then
        echo "[ERROR] MySQL ${MYSQL_INSTALL_FLAG} is not exist !"
	return 1
    fi

    printf "[INFO] %-40s is pass!\n" "MySQL"
}

function installMysql()
{
    echo "[Function] Install Mysql now!"

    rpmMysql=`rpm -qa | grep -i mysql`

    rpm -qa | grep -i mysql >/dev/null 2>&1

    if [[ $? -eq 0 ]];then
        yum remove mysql mysql-server mysql-libs compat-mysql51
	rm -rf /var/lib/mysql*
	rm -f /etc/my.cnf
    fi

    echo "MySQL pkg path $TOOLS_DIR/$MYSQL_PKG"

    if [[ ! -f "$TOOLS_DIR/$MYSQL_PKG" ]];then
        echo "[WARN] pgk $TOOLS_DIR/$MYSQL_PKG is not exists!"
        echo "[INFO] Start scp ${TOOLS_DIR}/${MYSQL_PKG} from backup machine!"
        su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${MYSQL_PKG} /cloud/tools"
        if [[ ! -f ${TOOLS_DIR}/${MYSQL_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${MYSQL_PKG} from backup machine failed, please check!"
            return 1
        fi
    fi

    chmod 755 "$TOOLS_DIR/$MYSQL_PKG"

    chown dbuser: "$TOOLS_DIR/$MYSQL_PKG"

    echo "Install path $MYSQL_HOME"
    rm -rf "$MYSQL_HOME"

    if [[ ! -d "$MYSQL_HOME" ]];then
        mkdir -p "$MYSQL_HOME"
        chmod 755 "$MYSQL_HOME"
        chown dbuser: "$MYSQL_HOME"
    fi

    su dbuser -c "tar -zxf \"$TOOLS_DIR/$MYSQL_PKG\" -C \"$MYSQL_HOME\""
    su dbuser -c "touch ${MYSQL_INSTALL_FLAG}"
    su dbuser -c "mkdir -p  /cloud/db/mysql/mysql${MYSQL_PORT}/{data,binlog,relaylog,logs,slowlog}"

    rpm -qa | grep perl-devel > /dev/null 2>&1
    if [[ $? -ne 0 ]];then
        yum -y install perl-devel > /dev/null 2>&1
    fi
    
    rpm -qa | grep "ncurses" > /dev/null 2>&1

    if [[ $? -ne 0 ]];then
        yum -y install libncurses* > /dev/null 2>&1
    fi
}

function checkMySQLConfig()
{
    echo "[Function] Check MySQL configuration!"

    if [[ "$1"x == "cloud1"x || "$1"x == "backup"x ]];then
        echo "[INFO] The node is no need install MySQL!"
	return 0
    fi

    cat > /etc/my.cnf <<EOF
[mysqld_multi]

mysqld=/cloud/db/mysql/mysql-5.7.32-el7-x86_64/bin/mysqld_safe
mysqladmin=/cloud/db/mysql/mysql-5.7.32-el7-x86_64/bin/mysqladmin
log=/cloud/db/mysql/mysqld_multi.log

[mysqld16603]
basedir=/cloud/db/mysql/mysql-5.7.32-el7-x86_64/
port=16603
server_id=16603
user=dbuser
socket=/cloud/db/mysql/mysql16603/mysql16603.sock
pid-file=/cloud/db/mysql/mysql16603/mysql16603.pid
datadir=/cloud/db/mysql/mysql16603/data/
skip-external-locking
log-bin=/cloud/db/mysql/mysql16603/binlog/mysql-bin
relay_log=/cloud/db/mysql/mysql16603/relaylog/relay-bin
log-error=/cloud/db/mysql/mysql16603/logs/mysql16603.log
slow_query_log=1
slow_query_log_file=/cloud/db/mysql/mysql16603/slowlog/slow.log

# GTID for Master
gtid_mode=on
enforce_gtid_consistency=on
log_bin=on
server_id=16603
binlog_format=row

#需要同步的二进制数据库名
binlog-do-db=lsq_db
binlog-do-db=test_db
#只保留7天的二进制日志，以防磁盘被日志占满(可选)
expire-logs-days = 7
#不备份的数据库
binlog-ignore-db=information_schema
binlog-ignore-db=performation_schema
binlog-ignore-db=sys

EOF


    mysqlHomeEnv=`cat /home/dbuser/.bashrc | grep MYSQL_HOME`

    if [[ -z ${mysqlHomeEnv} ]];then
        echo "MYSQL_HOME=/cloud/db/mysql/mysql-5.7.32-el7-x86_64" >> /home/dbuser/.bashrc
        echo "PATH=\$PATH:\$MYSQL_HOME/bin" >> /home/dbuser/.bashrc
        echo "export PATH" >> /home/dbuser/.bashrc
    fi

    . /home/dbuser/.bashrc

    echo "[INFO] Start init Mysql!"

    if [ "$(ls -A ${DB_DIR}/mysql/mysql${MYSQL_PORT}/data)" ]; then
        echo "[INFO] mysql${MYSQL_PORT} has been initialized!"
        return 0
    fi

    if [[ -d "${DB_DIR}/mysql/mysql${MYSQL_PORT}" ]];then
        su dbuser -c "mysqld --initialize-insecure --user=dbuser --datadir=${DB_DIR}/mysql/mysql${MYSQL_PORT}/data/ --basedir=${DB_DIR}/mysql/mysql-5.7.32-el7-x86_64 > ${MYSQL_INIT_LOG}" > /dev/null 2>&1
    fi

    echo "[INFO] End init Mysql!"
}

function isMongoInstalled()
{
    echo "[Function] Check MongoDB is installed?"

}

function installMongoDB()
{
    echo "[Function] Install MongoDB now!"
}

function isRedisInstalled()
{
    echo "[Function] Check Redis is installed?"

    if [[ "$1"x == "cloud1"x || "$1"x == "backup"x ]];then
        echo "[INFO] The node is no need install Redis!"
	return 0
    fi

    if [[ ! -f ${REDIS_INSTALL_FLAG} ]];then
        echo "[WARN] REDIS ${REDIS_INSTALL_FLAG} is not exist !"
	return 1
    fi

    printf "[INFO] %-40s is pass!\n" "REDIS"
}

function installRedis()
{
    echo "[Function] Install Redis now!"

    echo "Redis pkg path $TOOLS_DIR/$REDIS_PKG"

    if [[ ! -f "${TOOLS_DIR}/${REDIS_PKG}" ]];then
        echo "[WARN] pgk ${TOOLS_DIR}/${REDIS_PKG} is not exists!"

        echo "[INFO] Start scp ${TOOLS_DIR}/${REDIS_PKG} from backup machine!"

        su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${REDIS_PKG} /cloud/tools"
        if [[ ! -f ${TOOLS_DIR}/${REDIS_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${REDIS_PKG} from backup machine failed, please check!"
            return 1
        fi
    fi

    chmod 755 "$TOOLS_DIR/$REDIS_PKG"

    chown dbuser: "$TOOLS_DIR/$REDIS_PKG"

    echo "Install path $REDIS_HOME"
    rm -rf "$REDIS_HOME"

    mkdir -p ${REDIS_HOME}
    mkdir -p ${REDIS_BIN}
    mkdir -p "${REDIS_SRC}"
    mkdir -p ${REDIS_HOME}/{redis16605,redis16606}/{data,logs}

    chmod -R 755 "$REDIS_HOME"
    chown -R dbuser: "$REDIS_HOME"

    su dbuser -c "tar -zxf \"$TOOLS_DIR/$REDIS_PKG\" -C \"$REDIS_SRC\""
    su dbuser -c "touch ${REDIS_INSTALL_FLAG}"

    mv /cloud/db/redis/redis_src/redis-5.0.7/*  /cloud/db/redis/redis_src/

    cd /cloud/db/redis/redis_src

    make > /dev/null 2>&1
    make install > /dev/null 2>&1

    mv /cloud/db/redis/redis_src/src/redis-cli ${REDIS_BIN}
    mv /cloud/db/redis/redis_src/src/redis-server ${REDIS_BIN}
}

function checkRedisConfig()
{
    echo "[Function] Check Redis configuration!"

    if [[ "$1"x == "cloud1"x || "$1"x == "backup"x ]];then
        echo "[INFO] The node is no need install Redis!"
	return 0
    fi

    cloud_host_ip=${CLOUD2_IP}

    if [[ "$1"x == "cloud3"x ]];then
        cloud_host_ip=${CLOUD3_IP}
    fi

    cat > ${REDIS_HOME}/redis16605/redis16605.conf <<EOF
bind ${cloud_host_ip} 127.0.0.1
requirepass redis2030
protected-mode yes
port 16605
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /cloud/db/redis/redis16605/redis16605.pid
loglevel notice
logfile "/cloud/db/redis/redis16605/logs/redis16605.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump_redis16605.rdb
dir /cloud/db/redis/redis16605/data/
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly_redis16605.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

EOF

    redis_home_env=`cat /home/dbuser/.bashrc | grep REDIS_HOME`

    if [[ -z ${redis_home_env} ]];then
        echo "REDIS_BIN=/cloud/db/redis/redis_src/src" >> /home/dbuser/.bashrc
        echo "PATH=\$PATH:\$REDIS_BIN" >> /home/dbuser/.bashrc
        echo "export PATH" >> /home/dbuser/.bashrc
    fi

    . /home/dbuser/.bashrc

}

function isZookeeperInstalled()
{
    echo "[Function] Check Zookeeper is installed?"
    
    if [[ -f ${ZK_INSTALL_FLAG} ]];then
        printf "[INFO] %-40s is pass!\n" "Zookeeper"
        return 0
    else
        return 1
    fi

    clientPortListern=`lsof -i:${ZK_CLIENT_PORT} | grep ${ZK_CLIENT_PORT} | grep "LISTEN"`
    if [[ -z $clientPortListern ]];then
        echo "[ERROR] ZK_CLIENT_PORT is not listern!"
    fi

    electPortListern=`lsof -i:${ZK_ELECT_PORT} | grep ${ZK_ELECT_PORT} | grep "LISTEN"`
    if [[ -z $electPortListern ]];then
        echo "[ERROR] ZK_ELECT_PORT is not listern!"
    fi
    clusterPortListern=`lsof -i:${ZK_CLUSTER_PORT} | grep ${ZK_CLUSTER_PORT} | grep "LISTEN"`
    if [[ -z $clusterPortListern ]];then
        echo "[ERROR] ZK_CLUSTER_PORT is not listern!"
    fi

    if [[ ! -d $ZOOKEEPER_HOME ]];then
        echo "[ERROR] $ZOOKEEPER_HOME is not exist!"
    fi

    if [[ -z $clientPortListern && -z $electPortListern && -z $clusterPortListern && ! -d $ZOOKEEPER_HOME || -d $ZOOKEEPER_HOME && ! -f $ZK_INSTALL_FLAG ]];then
        echo "[ERROR] ZOOKEEPER is not installed!"
	return 1
    fi
}

function installZookeeper()
{
    echo "[Function] Install Zookeeper now!"

    if [[ ! -f ${TOOLS_DIR}/${ZOOKEEPER_PKG} ]];then
        echo "[WARN] ${TOOLS_DIR}/${ZOOKEEPER_PKG} is not exist!"
        echo "[INFO] Start scp ${TOOLS_DIR}/${ZOOKEEPER_PKG} from backup machine!"
	su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${ZOOKEEPER_PKG} /cloud/tools"
        if [[ ! -f ${TOOLS_DIR}/${ZOOKEEPER_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${ZOOKEEPER_PKG} from backup machine failed, please check!"
	    return 1
	fi
    fi

    if [[ ! -d ${ZOOKEEPER_HOME} ]];then
        mkdir -p ${ZOOKEEPER_HOME}
    fi

    rm -rf ${ZOOKEEPER_HOME}/*
    tar -zxf ${TOOLS_DIR}/${ZOOKEEPER_PKG} -C ${ZOOKEEPER_HOME}
    mv ${ZOOKEEPER_HOME}/apache-zookeeper-3.5.7-bin/* ${ZOOKEEPER_HOME}
    rm -rf ${ZOOKEEPER_HOME}/apache-zookeeper-3.5.7-bin
    touch ${ZK_INSTALL_FLAG}
    if [[ ! -d $ZK_DATA_DIR ]];then
        mkdir -p $ZK_DATA_DIR
    fi
    if [[ ! -d $ZK_DATA_LOG_DIR ]];then
        mkdir -p $ZK_DATA_LOG_DIR
    fi
    chown -R ituser:cloudgroup ${ZOOKEEPER_HOME}
    chmod -R 755 ${ZOOKEEPER_HOME}
}

function checkZookeeperConfig()
{
    echo "[Function] Check Zookeeper configuration!"

    if [[ ! -f $ZK_CONFIG ]];then
        echo "[ERROR] $ZK_CONFIG is not exist!"
    fi

    echo "tickTime=2000" > $ZK_CONFIG
    echo "initLimit=10" >> $ZK_CONFIG
    echo "syncLimit=5" >> $ZK_CONFIG
    echo "dataLogDir=$ZK_DATA_LOG_DIR" >> $ZK_CONFIG
    echo "dataDir=$ZK_DATA_DIR" >> $ZK_CONFIG
    echo "clientPort=$ZK_CLIENT_PORT" >> $ZK_CONFIG
    echo "server.1=${CLOUD1_IP}:$ZK_CLUSTER_PORT:$ZK_ELECT_PORT" >> $ZK_CONFIG
    echo "server.2=${CLOUD2_IP}:$ZK_CLUSTER_PORT:$ZK_ELECT_PORT" >> $ZK_CONFIG
    echo "server.3=${CLOUD3_IP}:$ZK_CLUSTER_PORT:$ZK_ELECT_PORT" >> $ZK_CONFIG

    #if [[ ! -d $ZK_DATA_DIR ]];then
    #    mkdir -p $ZK_DATA_DIR
    #fi

    if [[ "$1"x == "cloud1"x ]];then
        echo "1" > $ZK_DATA_DIR/myid
    elif [[ "$1"x == "cloud2"x ]];then
        echo "2" > $ZK_DATA_DIR/myid
    elif [[ "$1"x == "cloud3"x ]];then
        echo "3" > $ZK_DATA_DIR/myid
    fi

    zookeeperHomeEnv=`cat /home/ituser/.bashrc | grep ZOOKEEPER_HOME`
    if [[ -z ${zookeeperHomeEnv} ]];then
        echo "ZOOKEEPER_HOME=/cloud/apps/zookeeper" >> /home/ituser/.bashrc
        echo "PATH=\$PATH:\$ZOOKEEPER_HOME/bin" >> /home/ituser/.bashrc
        echo "export PATH" >> /home/ituser/.bashrc
    fi
    . /home/ituser/.bashrc
    if [[ $? -eq 0 ]];then
        printf "[INFO] %-40s is pass!\n" "Zookeeper"
    fi
}

function isKafkaInstalled()
{
    echo "[Function] Check Kafka is installed?"

    if [[ -f $KAFKA_INSTALL_FLAG ]];then
        printf "[INFO] %-40s is pass!\n" "Kafka"
	return 0
    else
        echo "[WARN] KAFKA is not installed!"
	return 1
    fi
    portListern=`lsof -i:${KAFKA_PORT} | grep ${KAFKA_PORT} | grep "LISTEN"`
    if [[ -z $portListern ]];then
        echo "[ERROR] Kafka port ${KAFKA_PORT} is not listern!"
    fi
    if [[ ! -d $KAFKA_HOME ]];then
        echo "[ERROR] $KAFKA_HOME is not exist!"
    fi
    if [[ -z $portListern && ! -d $KAFKA_HOME || -d $KAFKA_HOME && ! -f $KAFKA_INSTALL_FLAG ]];then
        echo "[WARN] Kafka is not installed!"
	return 1
    fi
}

function installKafka()
{
    echo "[Function] Install Kafka now!"

    if [[ ! -f ${TOOLS_DIR}/${KAFKA_PKG} ]];then
        echo "[WARN] ${TOOLS_DIR}/${KAFKA_PKG} is not exist!"
        echo "[INFO] Start scp ${TOOLS_DIR}/${KAFKA_PKG} from backup machine!"
	su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${KAFKA_PKG} /cloud/tools"
        if [[ ! -f ${TOOLS_DIR}/${KAFKA_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${KAFKA_PKG} from backup machine failed, please check!"
	    return 1
	fi
    fi
    if [[ ! -d ${KAFKA_HOME} ]];then
        mkdir -p ${KAFKA_HOME}
    fi
    rm -rf ${KAFKA_HOME}/*
    tar -zxf ${TOOLS_DIR}/${KAFKA_PKG} -C ${KAFKA_HOME}
    mv ${KAFKA_HOME}/kafka_2.13-2.5.0/* ${KAFKA_HOME}
    rm -rf ${KAFKA_HOME}/kafka_2.13-2.5.0
    touch ${KAFKA_INSTALL_FLAG}
    if [[ ! -d ${KAFKA_LOG_DIR} ]];then
        mkdir -p ${KAFKA_LOG_DIR}
    fi
    if [[ -f ${KAFKA_SERVER_CONFIG} ]];then
        cp ${KAFKA_SERVER_CONFIG} ${KAFKA_SERVER_CONFIG}"_BAK"
    fi
    if [[ -f ${KAFKA_CONSUMER_CONFIG} ]];then
        cp ${KAFKA_CONSUMER_CONFIG} ${KAFKA_CONSUMER_CONFIG}"_BAK"
    fi
    if [[ -f ${KAFKA_PRODUCER_CONFIG} ]];then
        cp ${KAFKA_PRODUCER_CONFIG} ${KAFKA_PRODUCER_CONFIG}"_BAK"
    fi
    chown -R ituser:cloudgroup ${KAFKA_HOME}
    chmod -R 755 ${KAFKA_HOME}
}

function checkKafkaConfig()
{
    echo "[Function] Check Kafka configuration!"

    echo "${KAFKA_SERVER_CONFIG}"
    if [[ ! -f ${KAFKA_SERVER_CONFIG} ]];then
        echo "[ERROR] $KAFKA_SERVER_CONFIG is not exist!"
        return 1
    fi
    if [[ "$1"x == "cloud1"x ]];then
        cat ${KAFKA_SERVER_CONFIG} | grep "^broker.id=1" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/broker.id=.*/broker.id=1/g" ${KAFKA_SERVER_CONFIG}
        fi
        cat ${KAFKA_SERVER_CONFIG} | grep "^listeners=PLAINTEXT://${CLOUD1_IP}:${KAFKA_PORT}" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/#listeners=.*/listeners=PLAINTEXT:\/\/${CLOUD1_IP}:${KAFKA_PORT}/g" ${KAFKA_SERVER_CONFIG}
        fi
        cat ${KAFKA_SERVER_CONFIG} | grep "^advertised.listeners=PLAINTEXT://${CLOUD1_IP}:${KAFKA_PORT}" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/#advertised.listeners=.*/advertised.listeners=PLAINTEXT:\/\/${CLOUD1_IP}:${KAFKA_PORT}/g" ${KAFKA_SERVER_CONFIG}
        fi
    elif [[ "$1"x == "cloud2"x ]];then
        cat ${KAFKA_SERVER_CONFIG} | grep "^broker.id=2" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/broker.id=.*/broker.id=2/g" ${KAFKA_SERVER_CONFIG}
        fi
        cat ${KAFKA_SERVER_CONFIG} | grep "^listeners=PLAINTEXT://${CLOUD2_IP}:${KAFKA_PORT}" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/#listeners=.*/listeners=PLAINTEXT:\/\/${CLOUD2_IP}:${KAFKA_PORT}/g" ${KAFKA_SERVER_CONFIG}
        fi
        cat ${KAFKA_SERVER_CONFIG} | grep "^advertised.listeners=PLAINTEXT://${CLOUD2_IP}:${KAFKA_PORT}" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/#advertised.listeners=.*/advertised.listeners=PLAINTEXT:\/\/${CLOUD2_IP}:${KAFKA_PORT}/g" ${KAFKA_SERVER_CONFIG}
        fi
    elif [[ "$1"x == "cloud3"x ]];then
        cat ${KAFKA_SERVER_CONFIG} | grep "^broker.id=3" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/broker.id=.*/broker.id=3/g" ${KAFKA_SERVER_CONFIG}
        fi
        cat ${KAFKA_SERVER_CONFIG} | grep "^listeners=PLAINTEXT://${CLOUD3_IP}:${KAFKA_PORT}" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/#listeners=.*/listeners=PLAINTEXT:\/\/${CLOUD3_IP}:${KAFKA_PORT}/g" ${KAFKA_SERVER_CONFIG}
        fi
        cat ${KAFKA_SERVER_CONFIG} | grep "^advertised.listeners=PLAINTEXT://${CLOUD3_IP}:${KAFKA_PORT}" >/dev/null 2>&1
        if [[ $? -ne 0 ]];then
            sed -i "s/#advertised.listeners=.*/advertised.listeners=PLAINTEXT:\/\/${CLOUD3_IP}:${KAFKA_PORT}/g" ${KAFKA_SERVER_CONFIG}
        fi
    fi

    cat ${KAFKA_SERVER_CONFIG} | grep "^log.dirs=${KAFKA_LOG_DIR}" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        sed -i "s/log.dirs=.*/log.dirs=\/cloud\/apps\/kafka\/log/g" ${KAFKA_SERVER_CONFIG}
    fi
    cat ${KAFKA_SERVER_CONFIG} | grep "^zookeeper.connect=${ZK_CONNECT}" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        sed -i "s/zookeeper.connect=.*/zookeeper.connect=${ZK_CONNECT}/g" ${KAFKA_SERVER_CONFIG}
    fi

    if [[ ! -f ${KAFKA_CONSUMER_CONFIG} ]];then
        echo "[ERROR] $KAFKA_CONSUMER_CONFIG is not exist!"
        return 1
    fi
    if [[ ! -f ${KAFKA_PRODUCER_CONFIG} ]];then
        echo "[ERROR] $KAFKA_PRODUCER_CONFIG is not exist!"
        return 1
    fi
    cat ${KAFKA_CONSUMER_CONFIG} | grep "^bootstrap.servers=${KAFKA_BOOTSTRAP_SERVERS}" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        sed -i "s/bootstrap.servers=.*/bootstrap.servers=${KAFKA_BOOTSTRAP_SERVERS}/g" ${KAFKA_CONSUMER_CONFIG}
    fi
    cat ${KAFKA_PRODUCER_CONFIG} | grep "^bootstrap.servers=${KAFKA_BOOTSTRAP_SERVERS}" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        sed -i "s/bootstrap.servers=.*/bootstrap.servers=${KAFKA_BOOTSTRAP_SERVERS}/g" ${KAFKA_PRODUCER_CONFIG}
    fi
}

function isRocketMQInstalled()
{
    echo "[Function] Check RocketMQ is installed?"

    if [[ -f ${ROCKETMQ_INSTALL_FLAG} ]];then
	printf "[INFO] %-40s is pass!\n" "RocketMQ"
        return 0
    else
        return 1
    fi
}

function installRocketMQ()
{
    echo "[Function] Install RocketMQ now!"

    if [[ ! -f ${TOOLS_DIR}/${ROCKETMQ_PKG} ]];then
        echo "[ERROR] ${TOOLS_DIR}/${ROCKETMQ_PKG} is not exist!"

        echo "[INFO] Start scp ${TOOLS_DIR}/${ROCKETMQ_PKG} from backup machine!"

	su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${ROCKETMQ_PKG} /cloud/tools"

        if [[ ! -f ${TOOLS_DIR}/${ROCKETMQ_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${ROCKETMQ_PKG} from backup machine failed, please check!"
	    return 1
	fi
    fi

    if [[ ! -d ${ROCKETMQ_HOME} ]];then
        mkdir -p ${ROCKETMQ_HOME}
    fi

    rm -rf ${ROCKETMQ_HOME}/*

    chown -R ituser:cloudgroup ${ROCKETMQ_HOME}
    chmod -R 755 ${ROCKETMQ_HOME}
    chown -R ituser:cloudgroup ${TOOLS_DIR}/${ROCKETMQ_PKG}
    chmod -R 755 ${TOOLS_DIR}/${ROCKETMQ_PKG}

    su ituser -c "unzip ${TOOLS_DIR}/${ROCKETMQ_PKG} -d ${ROCKETMQ_HOME}" >/dev/null 2>&1

    mv ${ROCKETMQ_HOME}/rocketmq-all-4.8.0-bin-release/* ${ROCKETMQ_HOME}

    rm -rf ${ROCKETMQ_HOME}/rocketmq-all-4.8.0-bin-release

    touch ${ROCKETMQ_INSTALL_FLAG}
}

function checkRocketMQConfig()
{
    echo "[Function] Check RocketMQ configuration!"

    if [[ ! -f ${ROCKETMQ_BROKER_CONF} ]];then
        echo "[ERROR] ${ROCKETMQ_BROKER_CONF} is not exist!"
        return 1
    fi

    if [[ ! -f ${ROCKETMQ_RUN_SERVER_CONF} ]];then
        echo "[ERROR] ${ROCKETMQ_RUN_SERVER_CONF} is not exist!"
        return 1
    fi

    if [[ ! -f ${ROCKETMQ_RUN_BROKER_CONF} ]];then
        echo "[ERROR] ${ROCKETMQ_RUN_BROKER_CONF} is not exist!"
        return 1
    fi

    echo "listenPort=${ROCKETMQ_PORT}" > ${ROCKETMQ_NAMESRV_CONF}

    cat ${ROCKETMQ_BROKER_CONF} | grep "^brokerId" >/dev/null 2>&1
    if [[ $? -eq 0 ]];then
        echo "[INFO] change RocketMQ broker id..."
        if [[ $hostname == "cloud1" ]];then
            sed -i "s/brokerId = ./brokerId = 1/g" ${ROCKETMQ_BROKER_CONF}
        elif [[ $hostname == "cloud2" ]];then 
            sed -i "s/brokerId = ./brokerId = 2/g" ${ROCKETMQ_BROKER_CONF}
        elif [[ $hostname == "cloud3" ]];then 
            sed -i "s/brokerId = ./brokerId = 3/g" ${ROCKETMQ_BROKER_CONF}
        else
            echo "[WARN] hostname error!"
            return 1
        fi
    fi

    cat ${ROCKETMQ_BROKER_CONF} | grep "^autoCreateTopicEnable" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        echo "autoCreateTopicEnable=true" >> ${ROCKETMQ_BROKER_CONF}
    fi

    cloud_host_ip=${BACKUP_IP_EXT}

    cloud_host_name=`hostname`

    if [[ $cloud_host_name == "cloud1" ]];then
        cloud_host_ip=${CLOUD1_IP_EXT}
    elif [[ $cloud_host_name == "cloud2" ]];then
        cloud_host_ip=${CLOUD2_IP_EXT}
    elif [[ $cloud_host_name == "cloud3" ]];then
        cloud_host_ip=${CLOUD3_IP_EXT}
    else
        echo "[WARN] hostname error!"
        return 1
    fi

    cat ${ROCKETMQ_BROKER_CONF} | grep "^brokerIP1" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        echo "brokerIP1 = ${cloud_host_ip}" >> ${ROCKETMQ_BROKER_CONF}
    fi

    cat ${ROCKETMQ_BROKER_CONF} | grep "^namesrvAddr" >/dev/null 2>&1
    if [[ $? -ne 0 ]];then
        echo "namesrvAddr = ${cloud_host_ip}:${ROCKETMQ_PORT}" >> ${ROCKETMQ_BROKER_CONF}
    fi

}

function isRabbitMQInstalled()
{
    echo "[Function] Check RabbitMQ is installed?"
}

function checkDbUtils()
{
    echo "[Function] Check DB utils is send?"

    if [[ -f ${DB_UTIL} ]];then
        echo "[INFO] has DB utils..."
        return 0
    fi

    return 1
}

function checkAppUtils()
{
    echo "[Function] Check APP utils is send?"

    if [[ -f ${APP_UTIL} ]];then
        echo "[INFO] has APP utils..."
        return 0
    fi

    return 1
}

function getAppUtils()
{
    echo "[Function] Get APP utils from remote!"

    su ituser -c "scp -P ${SSH_PORT} ituser@backup:/cloud/utils/AppUtil.sh /home/ituser/"

    if [[ -f ${APP_UTIL} ]];then
        echo "[INFO] Get APP utils success!"
        return 0
    fi

    return 1
}


function getDbUtils()
{
    echo "[Function] Get DB utils from remote!"

    su ituser -c "scp -P ${SSH_PORT} ituser@backup:/cloud/utils/DbUtil.sh /home/ituser/"

    if [[ -f /home/ituser/DbUtil.sh ]];then
        echo "[INFO] Get DB utils success!"
        mv /home/ituser/DbUtil.sh /home/dbuser/
        chown -R dbuser: /home/dbuser
        return 0
    fi

    return 1
}
function installRabbitMQ()
{
    echo "[Function] Install RabbitMQ now!"
}

function checkRabbitMQConfig()
{
    echo "[Function] Check RabbitMQ configuration!"
}

function checkSparkConfig()
{
    echo "[Function] Check Spark configuration!"
}

function isHadoopInstalled()
{
    echo "[Function] Check Hadoop is installed?"
    if [[ -f ${HADOOP_INSTALL_FLAG} ]];then
	printf "[INFO] %-40s is pass!\n" "Hadoop"
        return 0
    else
        return 1
    fi
}

function installHadoop()
{
    echo "[Function] Install Hadoop now!"

    if [[ ! -f ${TOOLS_DIR}/${HADOOP_PKG} ]];then
        echo "[ERROR] ${TOOLS_DIR}/${HADOOP_PKG} is not exist!"
        echo "[INFO] Start scp ${TOOLS_DIR}/${HADOOP_PKG} from backup machine!"
	su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${HADOOP_PKG} /cloud/tools"
        if [[ ! -f ${TOOLS_DIR}/${HADOOP_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${HADOOP_PKG} from backup machine failed, please check!"
	    return 1
	fi
    fi

    if [[ ! -d ${HADOOP_HOME} ]];then
        mkdir -p ${HADOOP_HOME}
    fi

    rm -rf ${HADOOP_HOME}/*

    chown -R hadoop:cloudgroup ${HADOOP_HOME}
    chmod -R 755 ${HADOOP_HOME}
    chown -R hadoop:cloudgroup ${TOOLS_DIR}/${HADOOP_PKG}
    chmod -R 755 ${TOOLS_DIR}/${HADOOP_PKG}

    su hadoop -c "tar -zxf ${TOOLS_DIR}/${HADOOP_PKG} -C ${HADOOP_HOME}"

    mv ${HADOOP_HOME}/hadoop-3.3.0/* ${HADOOP_HOME}

    rm -rf ${HADOOP_HOME}/hadoop-3.3.0
    touch ${HADOOP_INSTALL_FLAG}
    #if [[ ! -d $ZK_DATA_LOG_DIR ]];then
    #    mkdir -p $ZK_DATA_LOG_DIR
    #fi
    if [[ -f ${HADOOP_CORE_XML} ]];then
        cp ${HADOOP_CORE_XML} ${HADOOP_CORE_XML}"_BAK"
    fi

    if [[ -f ${HADOOP_HDFS_XML} ]];then
        cp ${HADOOP_HDFS_XML} ${HADOOP_HDFS_XML}"_BAK"
    fi

    if [[ ! -f ${HADOOP_MAPRED_XML} ]];then
        cp ${HADOOP_MAPRED_XML} ${HADOOP_MAPRED_XML}"_BAK"
    fi

    if [[ ! -f ${HADOOP_YARN_XML} ]];then
        cp ${HADOOP_YARN_XML} ${HADOOP_YARN_XML}"_BAK"
    fi

    mkdir -p ${HADOOP_HOME}/{tmp,var,logs}
    mkdir -p ${HADOOP_HOME}/dfs/{name,data,checkpoint,edits}

    chown -R hadoop:cloudgroup ${HADOOP_HOME}
    chmod -R 755 ${HADOOP_HOME}
}

function checkHadoopConfig()
{
    echo "[Function] Check Hadoop configuration!"

    if [[ ! -f ${HADOOP_ENV_PATH} ]];then
        echo "[ERROR] ${HADOOP_ENV_PATH} is not exists!"
        return 1
    fi

    if [[ ! -f ${HADOOP_ENV_SH} ]];then
        echo "[ERROR] ${HADOOP_ENV_SH} is not exists!"
        return 1
    fi

    if [[ ! -f ${HADOOP_WORKERS} ]];then
        echo "[ERROR] ${HADOOP_WORKERS} is not exists!"
        return 1
    fi

    cat ${HADOOP_ENV_PATH} | grep "HADOOP_HOME"
    if [[ $? -ne 0 ]];then
        echo "export HADOOP_HOME=${HADOOP_HOME}" >> ${HADOOP_ENV_PATH}
        echo "export PATH=\$PATH:\$HADOOP_HOME/bin:\$HADOOP_HOME/sbin" >> ${HADOOP_ENV_PATH}
    fi

    cat ${HADOOP_ENV_SH} | grep "jdk1.8"
    if [[ $? -ne 0 ]];then
        echo "export JAVA_HOME=${JAVA_HOME}" >> ${HADOOP_ENV_SH}
    fi

    cat ${HADOOP_WORKERS} | grep "cloud"
    if [[ $? -ne 0 ]];then
        echo "cloud2" > ${HADOOP_WORKERS}
        echo "cloud3" >> ${HADOOP_WORKERS}
    fi

    if [[ ! -f ${HADOOP_CORE_XML} ]];then
        echo "[ERROR] ${HADOOP_CORE_XML} is not exists!"
        return 1
    fi

    if [[ ! -f ${HADOOP_HDFS_XML} ]];then
        echo "[ERROR] ${HADOOP_HDFS_XML} is not exists!"
        return 1
    fi

    if [[ ! -f ${HADOOP_MAPRED_XML} ]];then
        echo "[ERROR] ${HADOOP_MAPRED_XML} is not exists!"
        return 1
    fi

    if [[ ! -f ${HADOOP_YARN_XML} ]];then
        echo "[ERROR] ${HADOOP_YARN_XML} is not exists!"
        return 1
    fi

    cat > ${HADOOP_CORE_XML} <<EOF
    <property>
        <name>fs.checkpoint.period</name>
        <value>3600</value>
    </property>
    <property>
        <name>fs.checkpoint.size</name>
        <value>67108864</value>
    </property>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://cloud1:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>file:/cloud/apps/hadoop/tmp</value>
    </property>


EOF

    cat > ${HADOOP_HDFS_XML} <<EOF

    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>

    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/cloud/apps/hadoop/dfs/name</value>
    </property>

    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/cloud/apps/hadoop/dfs/data</value>
    </property>

    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>cloud1:50090</value>
    </property>

    <property>
        <name>dfs.namenode.http-address</name>
        <value>cloud1:50070</value>
        <description>
          The address and the base port where the dfs namenode web ui will listen on.
          If the port is 0 then the server will start on a free port.
        </description>
    </property> 

    <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>file:/cloud/apps/hadoop/dfs/checkpoint</value>
    </property>

    <property>
        <name>dfs.namenode.checkpoint.edits.dir</name>
        <value>file:/cloud/apps/hadoop/dfs/edits</value>
    </property>
EOF

    cat > ${HADOOP_MAPRED_XML} <<EOF
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapred.job.tarcker</name>
        <value>cloud1:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>cloud1:19888</value>
    </property>

EOF

    cat > ${HADOOP_YARN_XML} <<EOF
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>cloud1</value>
    </property>

    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <property>
        <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandle</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tarcker.address</name>
        <value>cloud1:8025</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>cloud1:8030</value>
    </property>
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>cloud1:8040</value>
    </property>
    <property>
        <name>yarn.resourcemanager.admin.address</name>
        <value>cloud1:8033</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>cloud1:8088</value>
    </property>

EOF

}

function isSparkInstalled()
{
    echo "[Function] Check Spark is installed?"

    if [[ ! -f ${SPARK_INSTALL_FLAG} ]];then
        printf "[INFO] %-40s is failed!\n" "Spark"
        return 1
    fi
    printf "[INFO] %-40s is pass!\n" "Spark"
    return 0
}

function installSpark()
{
    echo "[Function] Install Spark now!"

    if [[ ! -f ${TOOLS_DIR}/${SPARK_PKG} ]];then
        echo "[WARN] ${TOOLS_DIR}/${SPARK_PKG} is not exist!"
        echo "[INFO] Start scp ${TOOLS_DIR}/${SPARK_PKG} from backup machine!"
	su ituser -c "scp -P ${SSH_PORT} ituser@backup:${TOOLS_DIR}/${SPARK_PKG} /cloud/tools"
        if [[ ! -f ${TOOLS_DIR}/${SPARK_PKG} ]];then
            echo "[ERROR] scp ${TOOLS_DIR}/${SPARK_PKG} from backup machine failed, please check!"
	    return 1
	fi
    fi
    if [[ ! -d ${SPARK_HOME} ]];then
        mkdir -p ${SPARK_HOME}
    fi
    rm -rf ${SPARK_HOME}/*
    #su hadoop -c "tar -zxf ${TOOLS_DIR}/${SPARK_PKG} -C ${SPARK_HOME}"
    tar -zxf ${TOOLS_DIR}/${SPARK_PKG} -C ${SPARK_HOME}
    mv ${SPARK_HOME}/spark-3.0.2-bin-hadoop3.2/* ${SPARK_HOME}
    rm -rf ${SPARK_HOME}/spark-3.0.2-bin-hadoop3.2
    touch ${SPARK_INSTALL_FLAG}
    chown -R hadoop:cloudgroup ${SPARK_HOME}
    chmod -R 755 ${SPARK_HOME}
}

function isGitInstalled()
{
    echo "[Function] Check Git is installed?"
}

function checkSSHConfig()
{
    echo "[Function] Check ssh configuration!"
}

function forbidUserLogin()
{
    echo "[Function] Check JDK8 is installed?"
}

function forbidUserSuRoot()
{
    echo "[Function] Check JDK8 is installed?"
}

function usage()
{
    echo "[usage] bash MachineUtil.sh cloud2"
}

function printAllInfo()
{
    echo -e "\n**************************************************************\n"

    printf "[INFO] %-35s has installed!\n" "MySQL"
    printf "[INFO] %-35s has installed!\n" "Redis"
    printf "[INFO] %-35s has installed!\n" "RocketMQ"
    printf "[INFO] %-35s has installed!\n" "Kafka"
    printf "[INFO] %-35s has installed!\n" "Zookeeper"
    printf "[INFO] %-35s has installed!\n" "Docker"
    printf "[INFO] %-35s has installed!\n" "Kubernetes"
    printf "[INFO] %-35s can operate app eaily!\n" $APP_UTIL
    printf "[INFO] %-35s can operate db eaily!\n" $DB_UTIL
    printf "[INFO] %-35s can operate docker eaily!\n" $DOCKER_UTIL
    printf "[INFO] %-35s can operate kubernetes eaily!\n" $KUBERNETES_UTIL

    echo -e "\n**************************************************************\n"
}

function isPostgreSQLInstalled()
{
    # POSTGRESQL_PORT=16619
    echo "[Function] Check PostgreSQL is installed?"

}

function computeCost()
{
    endTime=`date +%Y-%m-%d_%H:%M:%S`
    endTime_s=`date +%s`

    sumTime=$(($endTime_s - $startTime_s ))
    costMinute=$(($sumTime / 60))
    costSecond=$(($sumTime % 60))

    echo "[INFO] Start: $startTime"
    echo "[INFO] End:   $endTime"
    echo "[INFO] Cost:  $costMinute minutes $costSecond seconds"
    echo ""
}


function fn_main()
{  
    if [ $# -eq 0 ];
    then
        usage
        exit
    fi

    checkParam "$1" || return $?
    checkHostname "$1" || return $?
    configSsh || return $?
    checkPipConf || return $?
    checkUser || return $?
    # checkUserPassword || return $?
    checkDir || return $?
    # checkMachineLearningDir || return $?
    checkDirPermission || return $?
    checkTools || return $?
    closeFirewall || return $?
    # checkAiPkgInstall $1 || return $?
    generateUserPubKey $1 || return $?
    # checkSshIsPass $1 || return $?
    # checkRemoteHostKeyIsUpdate $1 || return $?
    distributePubKey $1 || return $?
    checkJDKConfig || return $?
    isJDKInstalled || installJDK || isJDKInstalled ||return $?
    # isGccInstalled || installGcc || isGccInstalled ||return $?
    # isPythonInstalled || return $?
    checkYumConf || return $?
    isDockerInstalled $1 || installDocker || return $?
    isKubernetesInstalled $1 || installKubernetes $1 || return $?
    installKubernetesForMaster $1 || return $?
    isMysqlInstalled "$1" || installMysql || return $?
    isRedisInstalled "$1" || installRedis || return $?
    # isRabbitMQInstalled || installRabbitMQ || return $?
    isZookeeperInstalled || installZookeeper || return $?
    isKafkaInstalled || installKafka || return $?
    isRocketMQInstalled || installRocketMQ || return $?
    # isHadoopInstalled || installHadoop ||return $?
    # isSparkInstalled || installSpark || return $?
    checkRedisConfig "$1" || return $?
    checkMySQLConfig "$1" || return $?
    # checkRabbitMQConfig "$1" || return $?
    checkRocketMQConfig "$1" || return $?
    checkZookeeperConfig "$1" || return $?
    # checkHadoopConfig "$1" || return $?
    checkKafkaConfig "$1" || return $?
    # checkSparkConfig "$1" || return $?
    checkAppUtils || getAppUtils || return $?
    checkDbUtils || getDbUtils || return $?
    printAllInfo
    computeCost
}

fn_main "$@"
result=$?

if [[ "$result" -eq 0 ]]
then
    echo "SUCCESS"
    echo "Work efficiently, have a nice day!"
else
    echo "FAILED"
fi
